<html>
<head>
   <script src="comm/socket.io.js"></script>
   <script src="comm/comm.js"></script>
   <script src="utils/utils.js"></script>
   <script src="BigInt.js"></script>
</head>
<body onload="javascript:initForm();">

<script>

var worker1 = null;
var myAddress = null;

function receiveMessage(address, payload) {
  if (payload.type == "SET_VARIABLE") {
      setVariable(payload.data.name, payload.data.value);
  } else if (payload.type == "DHT") {
      receiveDHTMessage(address, payload);
  }
}

function getData(id) {
    var db = openDatabase('p2pjs_db', '1.0', 'P2PJS Temp Database', 1024); 
    var rs = null;
    db.transaction(function(tx) { 
        rs = tx.executeSql("SELECT value FROM DATA WHERE id = ?", [id]);
    });
    if (rs.rows.length == 0) {
        return null;
    } else {
        return JSON.parse(rs.rows.item(0).value);
    }
}

function receiveDHTMessage(address, payload) {
  var msg = new Object();
  msg.type = "DATA";
  msg.data = new Object();
  msg.data.address = address;
  msg.data.payload = payload.data;
  var stype = msg.data.payload.data.msg.type;
  if (stype == "GET_SUCCESSOR") {
      console.log("AAA: " + msg.data.payload.data.correlationId);
      console.log("BBB: " + msg.data.payload.data.replyToAddress);
      console.log("CCC: " + msg.data.payload.data.msg.data.key);
      //getSuccessorLocal(replyToAddress, correlationId, msg.data.payload);
  }
  worker1.postMessage(msg);
}

function setRemoteVariable(address, name, value) {
    var msg = new Object();
    msg.type = "SET_VARIABLE";
    msg.data = new Object();
    msg.data.name = name;
    msg.data.value = value;
    sendMessage(address, msg);
}

function getSuccessorLocal(replyToAddress, correlationId, msg) {
    console.log("getSuccessorLocal");
    var currentAddress = null;
    var myAddressBigInt = str2bigInt(this.dhtAddress, 16, 0, 0);
    var targetBigInt = mod(sub(str2bigInt(msg.data.key, 16, 0, 0), myAddressBigInt), maxVal);
    for (var i = 0; i <= this.fingerTable.length; i++) {
        currentAddress = powMod(bigInt2, int2bigInt(i, 0, 0), maxVal);
        if (equals(targetBigInt, currentAddress)) {
            setRemoteVariable(replyToAddress, correlationId, this.fingerTable[i]);
            return;
        } else {
            if (greater(currentAddress, targetBigInt) || equals(currentAddress, bigInt0)) {
                var tmpAddress = this.fingerTable[i - 1];
                var val1 = powMod(bigInt2, int2bigInt(i - 1, 0, 0), maxVal);
                var val2 = mod(sub(str2bigInt(tmpAddress.node, 16, 0, 0), myAddressBigInt), maxVal);
                var val3 = mod(sub(val2, val1), maxVal);
                var val4 = mod(sub(targetBigInt, val1), maxVal);
                if (greater(val3, val4)) {
                    setRemoteVariable(replyToAddress, correlationId, tmpAddress);
                } else {
                    this.requestAsync(correlationId, replyToAddress, tmpAddress.address, msg);
                }
                return;
            }
        }
    }
}

function setVariable(name, value) {
  console.log("SET VAR:" + name + ":" + JSON.stringify(value));
  var db = openDatabase('p2pjs_db', '1.0', 'P2PJS Temp Database', 10240);
  db.transaction(function(tx) {
    tx.executeSql("INSERT OR REPLACE INTO MEMORY (correlationId, value) VALUES (?,?)", [name, JSON.stringify(value)]) ; 
  }) ;
}

function initMemory() {
  var db = openDatabase('p2pjs_db', '1.0', 'P2PJS Temp Database', 10240);
  db.transaction(function(tx) {
    tx.executeSql("CREATE TABLE IF NOT EXISTS MEMORY(correlationId TEXT, value TEXT)", []);
  });
}

function initData() {
  var db = openDatabase('p2pjs_db', '1.0', 'P2PJS Temp Database', 10240);
  db.transaction(function(tx) {
    tx.executeSql("CREATE TABLE IF NOT EXISTS DATA(id TEXT, value TEXT)", []);
  }); 
}

function initFT(size) {
  console.log("FFFFFFFFF");
  var db = openDatabase('p2pjs_db', '1.0', 'P2PJS Temp Database', 10240);
  db.transaction(function(tx) { 
    tx.executeSql("CREATE TABLE IF NOT EXISTS FINGER_TABLE(host TEXT, ix INTEGER, node TEXT, address TEXT)", []);
    tx.executeSql("DELETE FROM FINGER_TABLE WHERE host = ?", [myAddress]);
    console.log("HHHHH");
    for (var i = 0; i < size; i++) {
        tx.executeSql("INSERT INTO FINGER_TABLE (host, ix, node, address) VALUES (?,?,?,?)", [myAddress, i, "", ""]); 
    } 
  });
  console.log("XXXXXXXXX:" + db);
}

function initForm() {
  myAddress = generateAddress();
  document.getElementById('addressField').value = myAddress;
}

var RING_SIZE = 32;

function bootstrap() {
  initFT(RING_SIZE);
  initMemory();
  initData();
  var bootstrapAddress = document.getElementById('toAddressText').value;
  init_comm(myAddress, receiveMessage);
  worker1 = new Worker("app.js");
  worker1.abc = new Object();
  worker1.onmessage = function(event) {
    var msg = event.data;
    if (msg.type == "DATA") {
        var data = msg.data;
        sendMessage(data.address, data.payload);
    } else if (msg.type == "PRINT") {
        //document.getElementById('valueArea').value = msg.data;
        console.log(msg.data);
    }
  };
  worker1.postMessage({"type":"INIT", "myAddress":myAddress, "bootstrapAddress":bootstrapAddress});
}

function getResource() {
  var toAddress = document.getElementById('toAddressText').value;
  var id = document.getElementById('idText').value;
  var value = document.getElementById('valueArea').value;
  var msg = new Object();
  if (id == "FINGER_TABLE") {
    msg.type = "GET_FINGER_TABLE";
  } else if (id == "SUCCESSOR") {
    msg.type = "GET_SUCCESSOR";
    msg.data = new Object();
    msg.data.key = value;
  } else {
    msg.type = "GET_RESOURCE";
    msg.data = new Object();
    msg.data.id = id;
  }
  worker1.postMessage({"type":"PROC", "data":msg});
}

function putResource() {
  var toAddress = document.getElementById('toAddressText').value;
  var id = document.getElementById('idText').value;
  var value = document.getElementById('valueArea').value;
  var msg = new Object();
  msg.type = "PUT_RESOURCE";
  msg.data = new Object();
  msg.data.id = id;
  msg.data.value = value;
  worker1.postMessage({"type":"PROC", "data":msg});
}

function deleteResource() {
  var toAddress = document.getElementById('toAddressText').value;
  var id = document.getElementById('idText').value;
  var msg = new Object();
  msg.type = "DELETE_RESOURCE";
  msg.data = new Object();
  msg.data.id = id;
  worker1.postMessage({"type":"PROC", "data":msg});
}


</script> 

<h2>[p2p-js] Demo - DSM Test</h2>

<form name="form1">

My Address:- <br/> <input size="35" readonly="true" type="text" id="addressField" name="addressField" value="" /><br/><br/>

Bootstrap Address:- <br/> <input size="35" type="text" id="toAddressText" name="toAddressText" value="" /><br/><br/>

ID:- <br/> <input size="35" type="text" id="idText" name="idText" value="" /><br/><br/>

Value:- <br/> <textarea cols="35" rows="5" type="text" id="valueArea" name="valueArea" value=""></textarea><br/><br/>

<input type="button" value="Bootstrap" onclick="javascript:bootstrap();" /><br/>
<input type="button" value="GET RESOURCE" onclick="javascript:getResource();" />
<input type="button" value="PUT RESOURCE" onclick="javascript:putResource();" />
<input type="button" value="DELETE RESOURCE" onclick="javascript:deleteResource();" /><br/>

</form>

</body>
</html>

